#define    _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>


//1 文件间内容的作用域情况


//extern  int g_val;
//extern Add(int x, int y);
//
////程序执行时是所有文件的内容都执行的，另一个文件有main函数不能同时存在，而且文件间内容的传递要通过声明传递(全局变量需要声明后才能跨文件，静态变量不能跨文件，函数不用声明也能跨文件)
//int main()
//{
//	int a = 10;
//	int b = 20;
//	int c = 0;
//	c = Add(a, b);
//	printf("%d\n", c);
//	printf("%d\n", g_val);
//	return 0;
//}


//2 预定义符号
//#define x y -> 将y(可以是常量，变量，也可以是一段代码等等)等效代替成视为文本的x，即y可以用文本x等效代替表示
//预定义符号是现成已定义好的文本，可直接使用代替的


//int main()
//{
//	printf("%s\n", __FILE__);//__FILE__是进行编译的源文件名称(字符串)定义代替的文本
//	printf("%d\n", \
//		__LINE__);//此当前__LINE__在文件中所处的行号定义的文本
//	printf("%s\n", __DATE__);//文件被编译的日期定义的文本
//	printf("%s\n", __TIME__);//文件被编译的时间定义的文本
//	//printf("%d\n", __STDC__);//如果编译器完全遵循ANSI C(C语言标准)，其值是被定义成1的，否则未定义，说明vs并没有完全遵循ANSI C
//	return 0;
//}


//3


//#define CASE break;case//定义一段代码
//#define reg register
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	switch (n)
//	{
//	case 1:
//	//
//	CASE 2 :
//	//
//	CASE 3 :
//	//
//	break;
//	default:
//	//
//	}
//	register int num = 0;
//	reg int num2 = 0;//都能替换
//	return 0;
//}


//4 \续行符，\转义回车让回车不再是回车取消它意义变无意义，虽然形式上下去了但内容还是在上一行，这样数据在下行对应，把本来只能在同一行执行的代码拆成可在多行执行


//#define DEBUG_PRINTF printf("file:%s\
//\tline:%d\
//\t date:%s\
//\ttime:%s\
//\n",\
//__FILE__,\
//__LINE__,\
//__DATE__,\
//__TIME__)
////定义一段代码
//int main()
//{
//	DEBUG_PRINTF;
//	return 0;
//}


//5 #define定义符号的时候，最后不要加上分号


//#define M 100;
//int main()
//{
//	int a = M;
//	printf("%d\n",M);//err
//
//	int b = 0;
//	if (a > 3)
//		b = M;
//	else//err
//		b = -1;
//	return 0;
//}


//6 #define定义宏
//#define x y -> y是变量，实现将变量也定义为文本代替表示
//#define    name(paramentlist)               stuff
//                  参数列表    
//        左边这一整块是定义为的文本   右边这一块是变量的内容
//变量的内容代替定义为文本表示
//其中，name与(必须紧临，不然左边会视为纯文本不含参的那种
//-->name     (paramentlist)               stuff
//字符串(paramentlist)               stuff定义为name字符串代替
 

////定义一个宏，用来求平方
//#define SQUARE(n) ((n)*(n))
////将n*n定义替换为了SQUARE(n)这个有参数结合的文本
//int main()
//{
//	int x = 0;
//	scanf("%d", &x);
//	int ret = 0;
//	ret = SQUARE(x);
//	printf("%d\n", ret);
//
//	ret = SQUARE(5 + 1);//宏传过去的过程中是不加任何计算的，全部过去后才开始计算，所以内每一个n都要有括号，外n构成的整体外部也要有括号
//	//SQUARE(5+1)文本代替的是((5+1)*(5+1)) = 36
//	//如果定义视n*n不加括号 -> 5+1*5+1 = 11
//	printf("%d\n", ret);
//	return 0;
//}
//
////定义一个宏，用来求一个数的2倍
//#define DOUBLE(x) ((x)+(x))
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int ret = DOUBLE(n);
//	printf("%d\n", ret);
//	
//	ret = 10 * DOUBLE(5);
//	printf("%d\n", ret);
//	//10*((5)+(5)) = 100
//	//如果不加括号
//	//->10*5+5 = 55
//	return 0;
//}


//7 宏的参数在宏体如果是出现多次的话，那么当传过来的参数是带有副作用的表达式时，参数都换成副作用表达式，副作用就不是预想的只产生一次的了，而是会产生多次


////写一个宏，求2个数的较大值
//
//#define Max(X,Y) ((X)>(Y)?(X):(Y))
//
//int main()
//{
//	int a = 3;
//	int b = 5;
//	int m = Max(a++, b++);//与函数不同的是，函数传参传过去一次接的，宏传参传过去里面全替换的
//					   //选择语句，选择执行(b++)
//	//-> int m = ((a++)>(b++)?(a++):(b++));
//	//先针对到每一个变量，确定它们是++先还是表达式先，确定执行顺序
//	printf("m = %d\n", m);    
//	printf("a = %d\n", a);
//	printf("b = %d\n", b);
//
//	return 0;
//}


//8 


//#include<stdlib.h>
//
//#define Malloc(n,type) (type*)malloc(n*sizeof(type))
////宏都是替换式过去，文本式替换，什么都能替换
//int main()
//{
//	int* p = (int*)malloc(10 * sizeof(int));
//	//宏传的参可以是类型，函数不行
//	int* ptr = Malloc(10, int);
//}


//9


//int main()
//{
//	printf("hello""world\n");//"  " "  "引号内的对引号内无内容时的(可以是空格)对引号可消掉
//	printf("hello"   "world\n");//不是消掉是打印多个字符串，printf()是可以打印多个字符串的
//	printf("helloworld\n");
//	return 0;
//}


//10 #运算符 
//""字符串里的#a为"a"


//#define PRINTF(n,format) printf("the value of "#n" is "format"\n",n);
////内容肯定是成功替换的，但要符合printf函数的打印格式
// 
//int main()
//{
//	int a = 1;
//	PRINTF(a, "%d");//执行时执行的是文本全替换完后的
//	//printf("thr value of ""a"" is ""%d""\n",a);//这样就打印了5个字符串
//	//往printf""里传内容打印，打印的内容最后在里面要有两层""包裹才能把传的内容打印
//	int b = 20;
//	PRINTF(b, "%d");
//	float f = 5.6f;
//	PRINTF(f, "%f");
//	return 0;
//}


//11 ##运算符


////名字里的部分替换是无法实现的，type_max，参数type传来int时，不会把名字里的type替换成int，因为type_max被认为是一个符号而不是type符号
////宏的参数去找替换时它至少要按符号单位去替换的
////定义一个声明函数的宏 //函数模具  
//#define GENERIC_MAX(type)                 \
//       type type##_max(type x, type y)\
//      {                               \
//          return x>y?x:y;             \
//      }
////int int_max(int x, int y)
////{
////	return x > y ? x : y;\
////
//
////用宏替换完后是一个函数的声明 //利用宏实现可以一句代码批量造函数
//GENERIC_MAX(int);//int int_max(int x, int y){   return x>y?x:y;}
//GENERIC_MAX(float);
//
//int main()
//{
//	int r1 = int_max(3, 5);
//	printf("%d\n", r1);
//    float r2 = float_max(3.1f, 4.5f);
//    printf("%f\n", r2);
//    return 0;
//}


//12 #undef->undefine 移除一个宏定义


//#define MAX 100
//
//int main()
//{
//	printf("%d\n", MAX);
//#undef MAX
//	printf("%d\n", MAX);//err
//	return 0;
//}


//13 条件编译 


////1)#if ... #elif ... #else ... #endif
//int main()
//{
//#if 0
//	printf("hello\n");//不会编译的
//#elif 1
//	printf("hehe\n");
//#else
//	printf("haha\n");
//#endif
//	return 0;
//}
//
////2)#if defined() ... #endif <=> #ifdef  ... #endif //定义了为真，没定义为假,判断符号是否被程序员定义过
////#if !defined() <=> #ifndef 
////都可嵌套起来的
//#define MAX 3
////每一个#if(其实#ifdef、#ifndef都属于#if)都要有#endif匹配的，但#endif后就断了，不用{}#endif会自动找#if匹配
////一个词最多合成两个,elif、ifdef(ifndef)
//int main()
//{
//#ifdef MAX
//	printf("hehe\n");
//#elif 1
//	printf("hello\n");
////没有写293行if的else时的执行
//#endif//结束的就是291行的#ifdef
//
//
//#if 1
//	printf("hello\n");
//#else
//	#ifdef MIN
//		printf("b");
//	#endif
//	#ifdef A
//		printf("c");
//	#endif
//	#endif
//
//
//
//#ifdef A
//	#ifdef MAX
//		printf("abc\n");
//	#else
//		printf("hello\n");
//	#ifdef MIN
//		printf("hehe\n");
//	#else
//		printf("haha");
//	#endif
//	#endif
//#else// <==> elif defined(B)
//	#ifdef B
//		printf("123");
//	#else
//		printf("a");
//	#endif
//	#endif
//	return 0;
//}



#include"add.h"//查找该文件夹里一次，如果没有就往标准库里查找一次
#include<stdio.h>//之间往标准库里查找一次